package handlers

import (
	"GoServer/common"
	"GoServer/entrance/game/game_service"
	"GoServer/message"
	"GoServer/models"
	"GoServer/models/ks_models"
	"GoServer/net"
	"GoServer/net/ws"
	"GoServer/utils/databases"
	"GoServer/utils/debug"
	"GoServer/utils/tool"
	"context"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
	"time"
)

func OnKSLiveWarapper(c *gin.Context) {
	debug.Logln(debug.Info, "推送快手弹幕数据!!!")
	var wrapper ks_models.KSLiveGiftWrapper
	if err := c.ShouldBindJSON(&wrapper); err != nil {
		tool.Resp(c.Writer, message.ErrorMsg, gin.H{
			"result":   0,
			"errorMsg": "参数解析失败: " + err.Error(),
		}, "")
		debug.Logln(debug.Error, fmt.Sprintf("参数解析错误：%s", err.Error()))
		return
	}

	debug.Logln(debug.Debug, fmt.Sprintf("弹幕快手推送数据：%+v", wrapper))
	data := wrapper.Data

	// 幂等处理
	if isDuplicateMessage(data.UniqueMessageId) {
		tool.Resp(c.Writer, message.ErrorMsg, nil, "消息重复..")
		return
	}
	markMessageProcessed(data.UniqueMessageId)

	debug.Logln(debug.Debug, fmt.Sprintf("当前消息类型：%s", data.PushType))
	// 根据 push_type 做类型分发
	switch data.PushType {
	case "giftSend":
		handleGiftSend(c, data)
	case "liveComment":
		handleLiveComment(c, data)
	case "liveLike":
		handleLiveLike(c, data)
	default:
		debug.Logln(debug.Warn, "未处理的 push_type:", data.PushType)
		c.JSON(http.StatusOK, gin.H{
			"result":   0,
			"errorMsg": "不支持的 push_type: " + data.PushType,
		})
	}
}

func handleGiftSend(c *gin.Context, data ks_models.KSLiveGiftPayload) {
	roomID := data.RoomCode
	now := uint64(time.Now().UnixMilli())

	liveGifts := make([]models.LiveGift, 0, len(data.Payload))

	for _, payloadStr := range data.Payload {
		var gift ks_models.KSGiftData
		if err := json.Unmarshal([]byte(payloadStr), &gift); err != nil {
			debug.Logln(debug.Error, "payload 解析失败:", err, "原始内容:", payloadStr)
			continue
		}

		liveGift := models.LiveGift{
			MsgId:     gift.UniqueNo,
			SecOpenid: gift.UserInfo.UserId,
			SecGiftId: gift.GiftId,
			GiftNum:   gift.GiftCount,
			GiftValue: int64(gift.GiftUnitPrice), // 单位分
			AvatarUrl: gift.UserInfo.HeadUrl,
			NickName:  gift.UserInfo.UserName,
			Timestamp: now,
		}
		liveGifts = append(liveGifts, liveGift)

		// 送礼积分处理
		game_service.AddGiftScore(common.GameName, roomID, uint64(gift.GiftCount)*uint64(gift.GiftUnitPrice))
	}

	if len(liveGifts) == 0 {
		tool.Resp(c.Writer, message.ErrorMsg, gin.H{
			"result":   0,
			"errorMsg": "未能解析有效的礼物数据",
		}, "")
		return
	}

	// 发送给客户端或广播
	bodyBytes, err := json.Marshal(liveGifts)
	if err != nil {
		tool.Resp(c.Writer, message.ErrorMsg, gin.H{
			"result":   0,
			"errorMsg": "json 格式化失败: " + err.Error(),
		}, "")
		return
	}

	msg := &ws.LiveInteractiveData{
		Message: message.Message{
			MsgType: message.SCLiveGiftMsg,
			RoomId:  roomID,
		},
		Data: string(bodyBytes),
	}

	if ws.IsRoomID(roomID) {
		msg.SendToClient(roomID)
	} else {
		reqBody, _ := json.Marshal(msg)
		debug.Logln(debug.Info, "[礼物消息]没有找到此玩家的连接，广播给其他服务器:", string(reqBody))
		net.BroadcastMessage("live-message", string(reqBody))
	}

	c.JSON(http.StatusOK, gin.H{"result": 1})
}

func handleLiveComment(c *gin.Context, data ks_models.KSLiveGiftPayload) {
	roomID := data.RoomCode
	now := uint64(time.Now().UnixMilli())

	commentList := make([]models.LiveComment, 0, len(data.Payload))

	for _, payloadStr := range data.Payload {
		var comment ks_models.KSCommentData
		if err := json.Unmarshal([]byte(payloadStr), &comment); err != nil {
			debug.Logln(debug.Error, "评论 payload 解析失败:", err, "原始内容:", payloadStr)
			continue
		}

		commentList = append(commentList, models.LiveComment{
			SecOpenid: comment.UserInfo.UserId,
			NickName:  comment.UserInfo.UserName,
			AvatarUrl: comment.UserInfo.HeadUrl,
			Content:   comment.Content,
			Timestamp: now,
		})
	}

	if len(commentList) == 0 {
		c.JSON(http.StatusOK, gin.H{
			"result":   0,
			"errorMsg": "未能解析有效的评论数据",
		})
		return
	}

	bodyBytes, err := json.Marshal(commentList)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"result":   0,
			"errorMsg": "json 格式化失败: " + err.Error(),
		})
		return
	}

	msg := &ws.LiveInteractiveData{
		Message: message.Message{
			MsgType: message.SCLiveCommentMsg, // ⬅️ 替换成你系统定义的评论消息类型
			RoomId:  roomID,
		},
		Data: string(bodyBytes),
	}

	if ws.IsRoomID(roomID) {
		msg.SendToClient(roomID)
	} else {
		reqBody, _ := json.Marshal(msg)
		debug.Logln(debug.Info, "[评论消息]没有找到此玩家的连接，广播给其他服务器:", string(reqBody))
		net.BroadcastMessage("live-message", string(reqBody))
	}

	c.JSON(http.StatusOK, gin.H{"result": 1})
}

func handleLiveLike(c *gin.Context, data ks_models.KSLiveGiftPayload) {
	roomID := data.RoomCode
	now := uint64(time.Now().UnixMilli())

	likeList := make([]models.LiveLike, 0, len(data.Payload))

	for _, payloadStr := range data.Payload {
		var like ks_models.KSLikeData
		if err := json.Unmarshal([]byte(payloadStr), &like); err != nil {
			debug.Logln(debug.Error, "点赞 payload 解析失败:", err, "原始内容:", payloadStr)
			continue
		}

		likeList = append(likeList, models.LiveLike{
			SecOpenid: like.UserInfo.UserId,
			NickName:  like.UserInfo.UserName,
			AvatarUrl: like.UserInfo.HeadUrl,
			LikeNum:   strconv.Itoa(like.Count),
			Timestamp: now,
		})
	}

	if len(likeList) == 0 {
		c.JSON(http.StatusOK, gin.H{
			"result":   0,
			"errorMsg": "未能解析有效的点赞数据",
		})
		return
	}

	bodyBytes, err := json.Marshal(likeList)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"result":   0,
			"errorMsg": "json 格式化失败: " + err.Error(),
		})
		return
	}

	msg := &ws.LiveInteractiveData{
		Message: message.Message{
			MsgType: message.SCLiveLikeMsg, // ⬅️ 自定义你的点赞消息类型
			RoomId:  roomID,
		},
		Data: string(bodyBytes),
	}

	if ws.IsRoomID(roomID) {
		msg.SendToClient(roomID)
	} else {
		reqBody, _ := json.Marshal(msg)
		debug.Logln(debug.Info, "[点赞消息]没有找到此玩家的连接，广播给其他服务器:", string(reqBody))
		net.BroadcastMessage("live-message", string(reqBody))
	}

	c.JSON(http.StatusOK, gin.H{"result": 1})
}

func isDuplicateMessage(id string) bool {
	exists, _ := databases.Rediss.Exists(context.Background(), "ks:gift:msg:"+id).Result()
	return exists == 1
}

func markMessageProcessed(id string) {
	databases.Rediss.Set(context.Background(), "ks:gift:msg:"+id, 1, 10*time.Minute)
}
